﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.IO;
using System.Collections;

namespace MyLib
{
    public class ConvertUtil
    {
        #region Convert to other net type
        public static bool ToBoolean(object value)
        {
            return ToBoolean(value, false);
        }
        public static bool ToBoolean(object value,bool defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    bool rtn;
                    if (bool.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        string str;
                        if (value == null)
                        {
                            str = "";
                        }
                        else
                        {
                            str = value.ToString();
                        }
                       
                        if (str.Trim() == "1")
                        {
                            return true;
                        }
                        else if (str.Trim() == "0")
                        {
                            return false;
                        }
                        else
                        {
                            return defaultValue;
                        }
                    }
                }
                else if (value is int || value is short || value is long)
                {
                    long lng = Convert.ToInt64(value);
                    if (lng == 1)
                    {
                        return true;
                    }
                    else if (lng == 0)
                    {
                        return false;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToBoolean(value);
                }
            }
        }

        public static byte ToByte(object value)
        {
           return  ToByte(value, byte.MinValue);
        }
        public static byte ToByte(object value, byte defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    byte rtn;
                    if (byte.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToByte(value);
                }
            }
        }

        public static char ToChar(object value)
        {
            return ToChar(value,char.MinValue);
        }
        public static char ToChar(object value, char defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    char rtn;
                    if (char.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToChar(value);
                }
            }
        }

        public static string ToShortDateString(object obj)
        {
            if (obj == DBNull.Value || obj == null)
            {
                return "";
            }
            if (obj.ToString().Trim() == "")
            {
                return "";
            }
            DateTime dt = ConvertUtil.ToDateTime(obj);

            return dt.ToShortDateString();
        }

        public static DateTime ToDateTime(object value)
        {
            return ToDateTime(value,DateTime.MinValue);
        }
        public static DateTime ToDateTime(object value, DateTime defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    DateTime rtn;
                    if (DateTime.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToDateTime(value);
                }
            }
        }

        public static string ToShortDateString(string value)
        {
            DateTime dt = ToDateTime(value);
            if (dt == DateTime.MinValue)
            {
                return "";
            }
            return dt.ToShortDateString();
        }

        public static string ToShortDateString(DateTime value)
        {
            if (value == DateTime.MinValue)
            {
                return "";
            }
            return value.ToShortDateString();
        }

        public static decimal ToDecimal(object value)
        {
            return ToDecimal(value,0);
        }
        public static decimal ToDecimal(object value, decimal defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    decimal rtn;
                    if (decimal.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToDecimal(value);
                }
            }
        }

        public static double ToDouble(object value)
        {
            return ToDouble(value,0);
        }
        public static double ToDouble(object value, double defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    double rtn;
                    if (double.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToDouble(value);
                }
            }
        }

        public static short ToInt16(object value)
        {
            return ToInt16(value,0);
        }
        public static short ToInt16(object value, short defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    short rtn;
                    if (short.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToInt16(value);
                }
            }
        }

        public static int ToInt32(object value)
        {
            return ToInt32(value,0);
        }
        public static int ToInt32(object value, int defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    int rtn;
                    if (int.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToInt32(value);
                }
            }
        }

        public static long ToInt64(object value)
        {
            return ToInt64(value,0);
        }
        public static long ToInt64(object value, long defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    long rtn;
                    if (long.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToInt64(value);
                }
            }
        }

        public static sbyte ToSByte(object value)
        {
            return ToSByte(value,0);
        }
        public static sbyte ToSByte(object value, sbyte defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    sbyte rtn;
                    if (sbyte.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToSByte(value);
                }
            }
        }

        public static float ToSingle(object value)
        {
            return ToSingle(value,0);
        }
        public static float ToSingle(object value, float defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    float rtn;
                    if (float.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToSingle(value);
                }
            }
        }

        public static ushort ToUInt16(object value)
        {
            return ToUInt16(value,0);
        }
        public static ushort ToUInt16(object value, ushort defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    ushort rtn;
                    if (ushort.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToUInt16(value);
                }
            }
        }

        public static uint ToUInt32(object value)
        {
            return ToUInt32(value,0);
        }
        public static uint ToUInt32(object value, uint defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    uint rtn;
                    if (uint.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToUInt32(value);
                }
            }
        }

        public static ulong ToUInt64(object value)
        {
            return ToUInt64(value,0);
        }
        public static ulong ToUInt64(object value, ulong defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                if (value is string)
                {
                    ulong rtn;
                    if (ulong.TryParse(value.ToString(), out rtn))
                    {
                        return rtn;
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
                else
                {
                    return Convert.ToUInt64(value);
                }
            }
        }

        public static string ToString(object value)
        {
            return ToString(value,null);
        }
        public static string ToString(object value, string defaultValue)
        {
            value = GetObjectValue(value);
            if (value == null)
            {
                return defaultValue;
            }
            else
            {
                return Convert.ToString(value); 
            }
        }

        static object GetObjectValue(object value)
        {
            if (value == DBNull.Value)
            {
                value = null;
            }
            return value;
        }
        #endregion

        #region Convert To SqlText
        public static string ToSqlString(DateTime value)
        {
            if (value.Date == DateTime.MinValue)
            {
                return "null";
            }
            else
            {
                return value.ToString();
            }
        }

        public static string ToSqlString(string value)
        {
            return Convert.ToString(value).Trim().Replace("'", "''") ;
        }

        public static string ToSqlString(int value)
        {
            return Convert.ToString(value);
        }

        public static string ToSqlString(short value)
        {
            return Convert.ToString(value);
        }

        public static string ToSqlString(long value)
        {
            return Convert.ToString(value);
        }

        public static string ToSqlString(decimal value)
        {
            return Convert.ToString(value);
        }

        public static string ToSqlString(double value)
        {
            return Convert.ToString(value);
        }

        public static string ToSqlString(float value)
        {
            return Convert.ToString(value);
        }

        public static string ToSqlString(object value)
        {
            if (value == null)
            {
                return "null";
            }
            if (value == DBNull.Value)
            {
                return "null";
            }
            if (value is DateTime)
            {
                return ToSqlString((DateTime)value);
            }
            if (value is int)
            {
                return ToSqlString((int)value);
            }
            if (value is short)
            {
                return ToSqlString((short)value);
            }
            if (value is long)
            {
                return ToSqlString((long)value);
            }
            if (value is decimal)
            {
                return ToSqlString((decimal)value);
            }
            if (value is double)
            {
                return ToSqlString((double)value);
            }
            if (value is float)
            {
                return ToSqlString((float)value);
            }
            return ToSqlString(Convert.ToString(value));
        }
        //**

        #endregion

        #region Type Convertor
        private struct DbTypeMapEntry
        {
            public Type Type;
            public DbType DbType;
            public SqlDbType SqlDbType;
            public DbTypeMapEntry(Type type, DbType dbType, SqlDbType sqlDbType)
            {
                this.Type = type;
                this.DbType = dbType;
                this.SqlDbType = sqlDbType;
            }
        };

        #region Methods

        static List<DbTypeMapEntry> _DbTypeList;
        private static List<DbTypeMapEntry> DbTypeList
        {
            get
            {
                if (_DbTypeList == null)
                {
                    _DbTypeList = new List<DbTypeMapEntry>();

                    DbTypeMapEntry dbTypeMapEntry = new DbTypeMapEntry(typeof(bool), DbType.Boolean, SqlDbType.Bit);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(byte), DbType.Double, SqlDbType.TinyInt);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(byte[]), DbType.Binary, SqlDbType.Image);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(DateTime), DbType.DateTime, SqlDbType.DateTime);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(Decimal), DbType.Decimal, SqlDbType.Decimal);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(double), DbType.Double, SqlDbType.Float);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(Guid), DbType.Guid, SqlDbType.UniqueIdentifier);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(Int16), DbType.Int16, SqlDbType.SmallInt);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(Int32), DbType.Int32, SqlDbType.Int);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(Int64), DbType.Int64, SqlDbType.BigInt);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(object), DbType.Object, SqlDbType.Variant);
                    _DbTypeList.Add(dbTypeMapEntry);

                    dbTypeMapEntry = new DbTypeMapEntry(typeof(string), DbType.String, SqlDbType.VarChar);
                    _DbTypeList.Add(dbTypeMapEntry);
                }
                return _DbTypeList;
            }
        }
        /// <summary>
        /// Convert db type to .Net data type
        /// </summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static Type ToNetType(DbType dbType)
        {
            DbTypeMapEntry entry = Find(dbType);
            return entry.Type;
        }
        /// <summary>
        /// Convert TSQL type to .Net data type
        /// </summary>
        /// <param name="sqlDbType"></param>
        /// <returns></returns>
        public static Type ToNetType(SqlDbType sqlDbType)
        {
            DbTypeMapEntry entry = Find(sqlDbType);
            return entry.Type;
        }

        /// <summary>
        /// Convert .Net type to Db type
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static DbType ToDbType(Type type)
        {
            DbTypeMapEntry entry = Find(type);
            return entry.DbType;
        }

        /// <summary>
        /// Convert TSQL data type to DbType
        /// </summary>
        /// <param name="sqlDbType"></param>
        /// <returns></returns>
        public static DbType ToDbType(SqlDbType sqlDbType)
        {
            DbTypeMapEntry entry = Find(sqlDbType);
            return entry.DbType;
        }

        /// <summary>
        /// Convert .Net type to TSQL data type
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static SqlDbType ToSqlDbType(Type type)
        {
            DbTypeMapEntry entry = Find(type);
            return entry.SqlDbType;
        }

        /// <summary>
        /// Convert DbType type to TSQL data type
        /// </summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static SqlDbType ToSqlDbType(DbType dbType)
        {
            DbTypeMapEntry entry = Find(dbType);
            return entry.SqlDbType;
        }

        private static DbTypeMapEntry Find(Type type)
        {
            object retObj = null;
            for (int i = 0; i < DbTypeList.Count; i++)
            {
                DbTypeMapEntry entry = DbTypeList[i];
                if (entry.Type == type)
                {
                    retObj = entry;
                    break;
                }
            }
            if (retObj == null)
            {
                throw new ApplicationException("Referenced an unsupported Type");
            }
            return (DbTypeMapEntry)retObj;
        }

        private static DbTypeMapEntry Find(DbType dbType)
        {
            object retObj = null;
            for (int i = 0; i < DbTypeList.Count; i++)
            {
                DbTypeMapEntry entry = (DbTypeMapEntry)DbTypeList[i];
                if (entry.DbType == dbType)
                {
                    retObj = entry;
                    break;
                }
            }
            if (retObj == null)
            {
                throw new ApplicationException("Referenced an unsupported DbType");
            }
            return (DbTypeMapEntry)retObj;
        }

        private static DbTypeMapEntry Find(SqlDbType sqlDbType)
        {
            object retObj = null;
            for (int i = 0; i < DbTypeList.Count; i++)
            {
                DbTypeMapEntry entry = (DbTypeMapEntry)DbTypeList[i];
                if (entry.SqlDbType == sqlDbType)
                {
                    retObj = entry;
                    break;
                }
            }
            if (retObj == null)
            {
                throw new ApplicationException("Referenced an unsupported SqlDbType");
            }

            return (DbTypeMapEntry)retObj;
        }
        #endregion
        #endregion

        #region Convert To Byte
        /// <summary> 
        /// 将 Stream 转成 byte[] 
        /// </summary> 
        public static byte[] ToBytes(Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始 
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }
        /// <summary> 
        /// 将 byte[] 转成 Stream 
        /// </summary> 
        public static Stream ToStream(byte[] bytes)
        {
            Stream stream = new MemoryStream(bytes);
            return stream;
        }
        #endregion

        public static bool IsInt(string value)
        {
            try
            {                                   
                Convert.ToInt32(value);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static bool IsDecimal(string value)
        {
            try
            {
                Convert.ToDecimal(value);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static bool IsBoolean(string value)
        {
            try
            {
                Convert.ToBoolean(value);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static bool IsDateTime(string value)
        {
            try
            {
                Convert.ToDateTime(value);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static void FilterColumns(DataTable dt, ArrayList displayFields)
        {
            for (int i = dt.Columns.Count - 1; i >= 0; i--)
            {
                int j;
                for (j = 0; j < displayFields.Count; j++)
                {
                    if (dt.Columns[i].ColumnName == displayFields[j].ToString())
                        break;
                }
                if (j >= displayFields.Count)
                    dt.Columns.Remove(dt.Columns[i]);
            }
        }
    }
}
